package com.segersten.othello.service.rest;

import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;

import akka.actor.ActorRef;

import com.segersten.othello.service.akka.AkkaUtil;
import com.segersten.othello.service.akka.Auth;
import com.segersten.othello.service.akka.GameObjectPool;
import com.segersten.othello.service.akka.GameObjectReference;
import com.segersten.othello.service.akka.game.Action;
import com.segersten.othello.service.akka.game.AuthenticatedAction;
import com.segersten.othello.service.akka.game.AuthenticatedGiveUp;
import com.segersten.othello.service.akka.game.BoardActionResponse;
import com.segersten.othello.service.akka.game.BoardActorFactory;
import com.segersten.othello.service.akka.game.BoardState2;
import com.segersten.othello.service.akka.game.State;

@Path("/othello2")
public class OthelloBoardService2 {
    
    GameObjectPool gameObjectPool = new AkkaUtil();

	@GET
	@Produces({ MediaType.TEXT_PLAIN })
	public String start() {
		return "othello";
	}

	@GET
	@Path("/board/{boardId}")
	@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
	public BoardState2 getBoard(@PathParam(value = "boardId") String boardId) {
		return getBoard(boardId, 0);
	}

	@GET
	@Path("/board/{boardId}/{round}")
	@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
	public BoardState2 getBoard(@PathParam(value = "boardId") String boardId, @PathParam(value = "round") Integer round) {
		GameObjectReference actor = null;
		try {
			actor = gameObjectPool.actorFor(boardId);
		} catch (NullPointerException e) {
			return null;
		} catch (IllegalStateException e) {
			throw new WebApplicationException(500);
		}
		BoardState2 stateResponse = (BoardState2) gameObjectPool.ask(actor, new State());
		if (stateResponse.getTransform().size() < round) {
			// not created yet
			throw new WebApplicationException(404);
		}
		BoardState2 ret = stateResponse.subset(round);
		return ret;
	}
	
	@POST
	@Path("/board")
	@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
	public CreateBoardResponse createBoard(CreateBoardRequest request) {

		if (AuthenticateService.INSTANCE.isOK(request.getAuth()) == false) {
			throw new WebApplicationException(403);
		}
		BoardActorFactory factory = new BoardActorFactory(gameObjectPool);
		String actorRef = factory.createBoard(request.getPlayer1(), request.getPlayer2());

		return new CreateBoardResponse("/game/othello2/board/" + actorRef);
	}
	
	
	@POST
	@Path("/board/delete")
	@Produces({ MediaType.TEXT_PLAIN })
	public String giveUpAction(GiveUpRequest request) {
	    System.out.println("***** giveUpAction" +  request);
		GameObjectReference actor = null;
		try {
			String actorReference = request.getReference().getReference().replace("/game/othello2/board/", "");
			System.out.println("Deleting actor " + actorReference);
            actor = gameObjectPool.actorFor(actorReference);
		} catch (NullPointerException e) {
			throw new WebApplicationException(404);
		} catch (IllegalStateException e) {
			throw new WebApplicationException(500);
		}
				// Check userId & token
		Auth auth = request.getAuth();

		BoardActionResponse response = (BoardActionResponse) gameObjectPool.ask(actor, new AuthenticatedGiveUp(auth));
		System.out.println("***** giveUpAction done " + response);
		return response.name();
	}

	
	@POST
	@Path("/board/{boardId}")
	@Produces({ MediaType.TEXT_PLAIN })
	public String putBoardAction(@PathParam(value = "boardId") String boardId, ActionRequest request) {

		GameObjectReference actor = null;
		try {
			actor = gameObjectPool.actorFor(boardId);
		} catch (NullPointerException e) {
			throw new WebApplicationException(404);
		} catch (IllegalStateException e) {
			throw new WebApplicationException(500);
		}

		Auth auth = request.getAuth();
		Action action = request.getAction();
		BoardActionResponse resp = (BoardActionResponse) gameObjectPool.ask(actor, new AuthenticatedAction(auth, action));
		// TODO refactor this
		if (BoardActionResponse.OK.equals(resp)) {
			return "OK";
		} else if (BoardActionResponse.NotYourTurn.equals(resp)) {
			throw new WebApplicationException(409);
		} else if (BoardActionResponse.NonAuth.equals(resp)) {
			throw new WebApplicationException(403);
		} else {
			throw new WebApplicationException(500);
		}
	}

}
